package top.broncho.anpods.ui.widget

import android.content.Context
import android.os.Build
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.FrameLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.transition.TransitionManager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.android.synthetic.main.layout_popup.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.info
import top.broncho.anpods.R
import top.broncho.anpods.model.BatteryState
import top.broncho.anpods.model.ConnectionState
import top.broncho.anpods.util.*


class AnPodsDialog @JvmOverloads constructor(
    context: Context
) : BottomSheetDialog(context), AnkoLogger, CoroutineScope by MainScope() {
    private var applyConstraintSet = ConstraintSet()

    init {
        setContentView(R.layout.layout_popup)
        applyConstraintSet.clone(anpods_panel)
        window?.run {
            setType(
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY else WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
            )
            delegate?.findViewById<View>(R.id.design_bottom_sheet)
                ?.setBackgroundResource(android.R.color.transparent)
        }
        iv_case.tag = MODEL_AIR_PODS_NORMAL
        setOnShowListener {
            info { "dialog showing..." }
            updateAirPodsModel(context.getStr("key_model"))

            val connectionState = anpods_panel.tag
            if (connectionState != null && (connectionState as ConnectionState).isConnected) {
                iv_case.progress = 1f
                iv_case_left.progress = 1f
                iv_case_right.progress = 1f

                iv_left_pod.progress = 1f
                iv_right_pod.progress = 1f
                return@setOnShowListener
            }
            iv_case.playAnimation()
            iv_case_left.playAnimation()
            iv_case_right.playAnimation()

            iv_case_battery.playAnimation()
            iv_left_pod_battery.playAnimation()
            iv_right_pod_battery.playAnimation()
            iv_left_pod.playAnimation()
            iv_right_pod.playAnimation()
        }

        setOnDismissListener {
            info { "dialog dismiss..." }
            val connectionState = anpods_panel.tag
            if (connectionState != null && (connectionState as ConnectionState).isConnected) {
                return@setOnDismissListener
            }
            iv_case.progress = 0f
            iv_case_left.progress = 0f
            iv_case_right.progress = 0f

            iv_case_battery.progress = 0f
            tv_case.text = "-"
            iv_left_pod_battery.progress = 0f
            tv_left_pod.text = "-"
            iv_right_pod_battery.progress = 0f
            tv_right_pod.text = "-"
            iv_left_pod.progress = 0f
            iv_right_pod.progress = 0f
        }

        context.displayChange().onEach {
            onBackPressed()
        }.launchIn(this)
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        cancel()
    }

    override fun show() {
        super.show()
        //设置高度
        val bottomSheet =
            findViewById<View>(R.id.design_bottom_sheet) as FrameLayout
        val originLayoutParams =
            (bottomSheet.layoutParams as CoordinatorLayout.LayoutParams).apply {
                height = ViewGroup.LayoutParams.WRAP_CONTENT
                gravity = Gravity.CENTER_HORIZONTAL
            }
        bottomSheet.layoutParams = originLayoutParams
        val bottomSheetBehavior: BottomSheetBehavior<*> = BottomSheetBehavior.from(bottomSheet)
        bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
    }

    private fun showCase() {
        TransitionManager.beginDelayedTransition(anpods_panel)
        applyConstraintSet.setVisibility(R.id.iv_case, ConstraintSet.VISIBLE)
        applyConstraintSet.setVisibility(R.id.iv_case_left, ConstraintSet.VISIBLE)
        applyConstraintSet.setVisibility(R.id.iv_case_right, ConstraintSet.VISIBLE)
        applyConstraintSet.setVisibility(R.id.tv_case, ConstraintSet.VISIBLE)
        applyConstraintSet.setVisibility(R.id.iv_case_battery, ConstraintSet.VISIBLE)

        applyConstraintSet.connect(
            R.id.iv_left_pod,
            ConstraintSet.END,
            R.id.iv_case,
            ConstraintSet.START
        )
        applyConstraintSet.connect(
            R.id.iv_right_pod,
            ConstraintSet.START,
            R.id.iv_case,
            ConstraintSet.END
        )
        applyConstraintSet.applyTo(anpods_panel)
    }

    private fun hideCase() {
        TransitionManager.beginDelayedTransition(anpods_panel)
        applyConstraintSet.setVisibility(R.id.iv_case, ConstraintSet.GONE)
        applyConstraintSet.setVisibility(R.id.iv_case_left, ConstraintSet.GONE)
        applyConstraintSet.setVisibility(R.id.iv_case_right, ConstraintSet.GONE)
        applyConstraintSet.setVisibility(R.id.tv_case, ConstraintSet.INVISIBLE)
        applyConstraintSet.setVisibility(R.id.iv_case_battery, ConstraintSet.INVISIBLE)

        applyConstraintSet.connect(
            R.id.iv_left_pod,
            ConstraintSet.END,
            R.id.iv_right_pod,
            ConstraintSet.START
        )
        applyConstraintSet.connect(
            R.id.iv_right_pod,
            ConstraintSet.START,
            R.id.iv_left_pod,
            ConstraintSet.END
        )
        applyConstraintSet.applyTo(anpods_panel)
    }

    fun updateConnectedDevice(connectionState: ConnectionState) {
        val state = anpods_panel.tag
        if (state == connectionState) return
        anpods_panel.tag = connectionState

        if (connectionState.isConnected) {
            tv_title.text = connectionState.deviceName
            updateAirPodsBattery(true)
        } else {
            tv_title.text = context.getString(R.string.main_disconnected_title)
            updateAirPodsBattery(false)
        }
    }

    fun updateUI(it: BatteryState) {
        updateAirPodsBattery(false, isBatteryStateChange = true)

        updateAirPodsModel(it.model)

        if (it.caseBattery <= 10) {
            showCase()
            tv_case.text =
                if (it.caseBattery == 10) "100%" else "${it.caseBattery * 10 + 5}%"
            iv_case_battery.progress = (it.caseBattery + 0.5f) / 10f

        } else {
            hideCase()
        }
        if (it.leftBattery <= 10) {
            tv_left_pod.text =
                if (it.leftBattery == 10) "100%" else "${it.leftBattery * 10 + 5}%"
            iv_left_pod_battery.progress = (it.leftBattery + 0.5f) / 10f

        } else {
            tv_left_pod.text = "-"
            iv_left_pod_battery.progress = 0f
        }
        if (it.rightBattery <= 10) {
            tv_right_pod.text =
                if (it.rightBattery == 10) "100%" else "${it.rightBattery * 10 + 5}%"
            iv_right_pod_battery.progress = (it.rightBattery + 0.5f) / 10f
        } else {
            tv_right_pod.text = "-"
            iv_right_pod_battery.progress = 0f
        }
    }

    private fun updateAirPodsBattery(isLoading: Boolean, isBatteryStateChange: Boolean = false) {
        iv_pods_loading.visibility = if (isLoading) View.VISIBLE else View.INVISIBLE

        tv_left_pod.visibility = if (isLoading) View.INVISIBLE else View.VISIBLE
        iv_left_pod_battery.visibility = if (isLoading) View.INVISIBLE else View.VISIBLE
        tv_right_pod.visibility = if (isLoading) View.INVISIBLE else View.VISIBLE
        iv_right_pod_battery.visibility = if (isLoading) View.INVISIBLE else View.VISIBLE
        if (!isBatteryStateChange) {
            tv_case.visibility = if (isLoading) View.INVISIBLE else View.VISIBLE
            iv_case_battery.visibility = if (isLoading) View.INVISIBLE else View.VISIBLE
        }
    }

    private fun updateAirPodsModel(model: String) {
        if (iv_case.tag != model) {
            iv_case.tag = model
            iv_left_pod.setAnimation(if (model == MODEL_AIR_PODS_PRO) R.raw.airpod_left_pro else R.raw.airpod_left)
            iv_right_pod.setAnimation(if (model == MODEL_AIR_PODS_PRO) R.raw.airpod_right_pro else R.raw.airpod_right)
            iv_case.setAnimation(
                when (model) {
                    MODEL_AIR_PODS_PRO -> R.raw.case_empty_pro
                    MODEL_AIR_PODS_2 -> R.raw.case_empty_gen_two
                    else -> R.raw.case_empty_gen_one
                }
            )
            iv_case_left.setAnimation((if (model == MODEL_AIR_PODS_PRO) R.raw.case_left_pro else R.raw.case_left))
            iv_case_right.setAnimation((if (model == MODEL_AIR_PODS_PRO) R.raw.case_right_pro else R.raw.case_right))
        }
    }

}